home *** CD-ROM | disk | FTP | other *** search
- /* -*-C-*- dispchar.h */
- /*-->dispchar*/
- /**********************************************************************/
- /****************************** dispchar ******************************/
- /**********************************************************************/
-
- void
- dispchar(c)
- BYTE c; /* character number in current font */
-
- /***********************************************************************
-
- This procedure has the delicate job of OR'ing the current character
- raster description into the bitmap, where the character box extends
- horizontally from (xcorner .. xcorner+wp-1) and vertically from
- (ycorner .. ycorner+hp-1). The lower left corner coordinates
- (xcorner, ycorner) are related to the current point (xcp, ycp) as
- follows:
-
- <------wp------>
- ^ ................
- | ................
- | ................
- | ................
- | ................
- | ................
- | ................
- hp ................
- | ................
- | ................
- | ................
- | .....o.......... <-- (xcp,ycp) at "o"
- | ................ ^
- | ................ |
- | ................ |--- (hp - yoffp - 1)
- | ................ |
- v +............... v <-- (xcorner,ycorner) at "+"
- <--->
- |
- |
- xoffp
-
- The current PXL file format stores character rasters in 32-bit words,
- with the rightmost portion of the last word in each line beyond the
- edge of the character being all 0 bits. For efficiency, the OR
- operation is done a word at a time, and in general, each such word
- contributes to two words in the bitmap line.
-
- line line line
- |.........word.........|.........word.........|.........word.........|
-
- 32-bit chunks--> |.....chrast.....|.....chrast.....|.....chrast.....|
-
- |<---->|<------->|
- | |
- bits_to_current---^ ^--- bits_to_next
-
- Thus, each 32-bit chunk will be right-shifted (filling vacated
- positions at the left with 0 bits) leaving "bits_to_current" bits at
- the low end and then OR'd into the current word of the bitmap line.
-
- Since the C language right-shift operator may or may not propagate
- the sign bit (which is usually at the left), a compile-time flag,
- ARITHRSHIFT, is necessary to include an extra AND operation to remove
- them when the right-shift is implemented by an arithmetic
- (sign-propagating), rather than a logical, shift.
-
- The 32-bit chunk will then be left-shifted (with 0 bits filling
- vacated positions on the right) leaving "bits_to_next" bits at the
- high end and OR'd into the next word of the bitmap line.
-
- When the host word size exceeds 32 bits (e.g. DEC-10 or -20 36-bit
- word), the first step may in fact require a left shift, and the
- second step is then not needed. This is detected in the code below
- by "bits_to_next" being negative.
-
- ***********************************************************************/
- {
- register struct char_entry *tcharptr;
- COORDINATE x,xcorner,ycorner;
- UNSIGN16 ilimit;
- register INT16 bits_to_next;
- register UNSIGN16 i;
- UNSIGN32 word32;
- register UNSIGN32 *p;
- register UNSIGN32 *raster_word;
- register COORDINATE j;
-
- if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */
- return;
-
- tcharptr = &(fontptr->ch[c]);
-
- if (tcharptr->rasters == (UNSIGN32*)NULL)/* if rasters still on file */
- loadchar(c); /* go get them */
-
- if (tcharptr->rasters == (UNSIGN32*)NULL)
- return; /* character image must be empty */
-
- tcharptr->refcount++; /* update reference count */
- raster_word = tcharptr->rasters; /* pointer to first raster word */
-
- xcorner = xcp - tcharptr->xoffp;
- ycorner = ycp - (tcharptr->hp - tcharptr->yoffp - 1);
-
- if (DBGOPT(DBG_CHAR_DUMP))
- {
- NEWLINE(stdout);
- (void)printf(
- "dispchar(): (xcp,ycp) = (%d,%d) (xcorner,ycorner) = (%d,%d)",
- xcp,ycp,xcorner,ycorner);
- NEWLINE(stdout);
- (void)printf(" (wp,hp) = (%d,%d) (xoffp,yoffp) = (%d,%d)",
- tcharptr->wp,tcharptr->hp,tcharptr->xoffp,tcharptr->yoffp);
- NEWLINE(stdout);
- ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
- for (j = tcharptr->hp; j > 0; --j)
- {
- for (i = 0; i < ilimit; ++i)
- (void)printf(" %08lx",*raster_word++);
- NEWLINE(stdout);
- }
- raster_word = tcharptr->rasters;
- }
-
- for (j = tcharptr->hp; j > 0; --j) /* loop over hp rasters from */
- { /* top to bottom */
- x = xcorner; /* select horizontal position */
-
- if(ycorner+j-1 > 0 && ycorner+j-1 < YBIT)
- p = BITMAP(ycorner+j-1,x/HOST_WORD_SIZE);
- /* and find word on line */
- else
- p = BITMAP(YBIT,x/HOST_WORD_SIZE);
-
- ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
- for (i = 0; i < ilimit; ++i)
- { /* loop over current line */
- word32 = *raster_word++; /* get 32-bit portion of raster */
- bits_to_next = (INT16)((x % HOST_WORD_SIZE) - HOST_WORD_SIZE + 32);
-
- #if (HOST_WORD_SIZE > 32)
- if (bits_to_next < 0) /* then must left shift character raster */
- *p |= (word32 << (-bits_to_next)); /* and OR into line */
- else
- #endif
-
- {
- *p |=
- #if (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
- /* these compilers correctly use a logical right shift for */
- /* unsigned values */
- #else
- #if ARITHRSHIFT /* arithmetic right shift propagates a sign */
- /* bit which must be cleared by this AND */
- rightones[bits_to_next] &
- #endif /* ARITHRSHIFT */
- #endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
-
- (word32 >> bits_to_next); /* OR into line */
-
- if (bits_to_next > 0)
- *++p |= (word32 << (HOST_WORD_SIZE - bits_to_next));
- /* OR in any spill into next word */
- else if (bits_to_next == 0)
- ++p; /* ended at word boundary, so start new one */
- }
- x += 32; /* and update horizontal position */
- }
- }
- }
-
-